<?php 

require_once 'MainPageWidget.php';
/**
 * Класс-виджет для управления правами в сообществе
 *
 * @package default
 * @author Alexander Sibiryakov
 **/
class CommunityRightsWidget extends MainPageWidget
{
	public $title = 'Права сообщества';

	public $ajax_functions = array(
		'ajax_settings_form',
		'ajax_settings_submit',
	);
	public $widget_js_path = 'widget/community_rights.js';	

	public function render()
	{
		$community_oid = $this->getParam('community_oid', $this->acl_assistant->acl_data['comity_oid']);
		$operations = $this->acl_assistant->getAvailableOperations();
		
		$this->actions = array_map('is_int', array_flip($operations));
		$this->actions['access'] = $this->getParam('widget_url');

		return $this;
	} // end of function data
	
	public function ajax_settings_form()
	{
		$this->getAccessSettings($content);

		$view = $this->getView('WG_CommunityRights:settings');
		$view->data['widget'] = $content;
//		if ($tdi_id) $view->data['event_edit'] = 1;
		$html = $view->getContent();

		$this->ctx->cp->set_data($html);
	} // end of function ajax_showSettingsForm
	
	public function ajax_settings_submit ($url)
	{
		//$this->ajax_init();
		$info = php_parse_str($url);
		do {
			$info['tdi_id'] = $tdi->id;
			if (!($res = $this->saveAccess($info))) {
				$status = 'Ошибка сохранения данных';
				break;
			}
			$status = 0;
		} while (false);
		$this->ctx->cp->set_data($status);
	} // end of function ajax_settings_submit

	private function getAccessSettings (&$content)
	{
		$community_oid = $this->acl_assistant->acl_data['comity_oid'];
		$operations = $this->acl_assistant->getAvailableOperations($community_oid);
		
		// загрузить роли сообщества
		$community_roles = $this->loadCommunityRoles($community_oid);

		$acl_object = $community_oid;
		
		// загрузить операции доступные каждой роли
		$community_roles = $this->loadActionsForRoles($acl_object, $community_roles);
		
		// загрузить операции доступные над сообществом
		$community_actions = $this->loadActionsForCommunity($acl_object);		
		
		// сделать единую структуру
		foreach ($community_roles as $k=>$role) {
			$action_list = $this->mergeDefaultAndValues($community_actions, $role['actions'], 'name', 'action');
			$community_roles[$k]['action_list'] = $action_list;
		}

		$content['roles'] = $community_roles;
		$content['default']['tdi_actions'] = $community_actions;

		$ql = 'select objects where community.oid==:0';
		$rs = $this->ctx->store->find($ql, array($community_oid));
		$community = $rs->next();
		
		$t = $community->data;
		$t['oid'] = $community->id;
		$content['data'] = $t;
		$content['config'] = unserialize($t['config']);

		$content['actions'] = array_map('is_int', array_flip($operations));//array_fill_keys($operations, true);
		
		$content['actions']['submit'] = $this->getParam('widget_url');
		/*
		$content['actions']['edit_access'] = $this->getParam('widget_url').'&tdi_oid='.$community->id;
		$content['actions']['edit_settings'] = $this->getParam('widget_url').'&tdi_oid='.$community->id;
		*/
		$content['oid'] = $tdi_id;
	} // end of method getAccessSettings
	
	/**
	 * Подготовит структуру с ролями пригодную для вывода в шаблон
	 *
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	private function loadCommunityRoles ($community_oid)
	{

		// выдернем роли для сообщества
		$community_roles = $this->acl_assistant->getRolesList($community_oid);

		// выдернем все роли
		$roles_ql = 'select objects where role.oid > 0 order by role.level';
		$rs = $this->store->find($roles_ql);
		if ($rs) {
			$roles = array();
			while ($role = $rs->next()) {
				$t = $role->data;
				$t['id'] = $role->id;
				$roles[$role->id] = $t;
			}
		}

		$members = array();
		// соберем данные по всем ролям в одни массив
		$users_role = array();
		foreach ($community_roles as $k=>$role) {
			$ro = $roles[$role['id_object']];
			if ($ro['name'] == 'administrator') {
				unset($community_roles[$k]);
			} else {
				$community_roles[$k]['title'] = $ro['title'];
				$community_roles[$k]['name'] = $ro['name'];
			}
		}

		return $community_roles;
	} // end of function loadCommunityRoles
	
	
	/**
	 * Возвращает список доступных операций к объекту c $object_oid для каджой роли в массиве $roles
	 *
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	private function loadActionsForRoles ($object_oid, $roles)
	{
		foreach ($roles as $oid=>$role) {
			$actions = $this->acl_assistant->getAclbyRole($object_oid, $role['id_object']);
			$roles[$oid]['actions'] = $actions;
		}
		return $roles;
	} // end of function loadActionsForRoles
	
	/**
	 * Вернет список действий которыми можно управлять через GUI
	 *
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	private function loadActionsForCommunity($oid)
	{
		return $this->acl_assistant->listAcl($oid);
	} 

	private function mergeDefaultAndValues ($defaults, $values, $key_name, $key_name_v=NULL)
	{
		$key_name = 'name';
		if (!isset($key_name_v)) $key_name_v = $key_name;
		$res = array();
		foreach ($defaults as $k=>$v) {
			$default = $v;
			$value   = NULL;
			$key = $default[$key_name];
			foreach ($values as $ak=>$av) {
				if ($av[$key_name_v] === $key) {
					$value = $av;
					break;
				}
			}
			$res[$key]['value'] = $value;
			$res[$key]['default'] = $default;
		}
		return $res;
	} // end of function mergeDefaultAndValues
	
	
	public function saveAccess ($info)
	{
		$community_oid = $this->acl_assistant->acl_data['comity_oid'];
		
		$ql = 'select objects where community.oid==:0';
		$rs = $this->ctx->store->find($ql, array($community_oid));
		$community = $rs->next();
		
		if (isset($info['join_mode'])) {
			
			$config = unserialize($community->data['config']);
			
			// если переключили с режима "вход с премодерацией" на режим "свободный вход", то одобрить всве заявки
			if (($config['join_mode']=="moderated") && ($info['join_mode']=="free")) {
				$jc = $this->ctx->mm->getModel("JoinCommunity", "a");
				if (!$jc->approveAll()) return false;
			}
			
			$config['join_mode'] = $info['join_mode'];
			$community->data['config'] = serialize($config);
		}
		$community->save();
		
		// все роли сообщества
		$community_roles = $this->loadCommunityRoles($community_oid);
		// все возможные действия над tdi, ключи - их имена
		$community_actions = $this->loadActionsForCommunity($community_oid);

		// теперь посмотрим что нам прислали
		$acls = array();
		$res = 0;
		foreach ($community_roles as $role) {
			$role_oid = $role['id_object'];
			foreach ($community_actions as $act_name => $act_data) {
				// нам прислали установки экшенов для данной роли
				if (isset($info['acl'][$role_oid][$act_name])) {
					$acls[$act_name] = 1;
				} else {
					// если нет -- запрещаем
					$acls[$act_name] = 0;
				}
			}
			if ($this->acl_assistant->updateAcl($community_oid, $acls, $role_oid) > 0) {
				$res = 1;
			}
			
			unset($acls);
			
		}
		
		return $res;
	} // end of method saveAccess
	
}

?>
